package com.shijiezhijia.sjzjapp.demo.inject;

import android.util.Log;
import android.view.View;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Author tzc
 * @Time 2022/11/19 0019
 * Describe 描述
 */
public class InjectUtils {
    public static final void inject(Object context){
        //获得所有属性
        Class<?> clazz= context.getClass();
        Field[] fields=clazz.getDeclaredFields();
        for (Field field:fields) {
            Bind bind= field.getAnnotation(Bind.class);
            if (bind!=null){
                injectBind(context,clazz,bind,field);
            }
            BindListener bindListener=field.getAnnotation(BindListener.class);
            if (bindListener!=null){
                injectBindListener(context,clazz,bindListener,field);
            }
        }
    }

    private static void injectBindListener(Object context,Class<?> clazz,BindListener bind,Field field) {
        try {
            //获取到界面UI控件
            Method method=clazz.getMethod("findViewById",int.class);
            Object view=  method.invoke(context,bind.value());
            //view.setOnClickListener(listener)
            Method method2=view.getClass().getMethod(bind.type(),field.getType());
            //可以访问私有参数。不然获取不到值
            field.setAccessible(true);
            //field.get(context) 获取指定字段在当前对象中的值。
            method2.invoke(view,field.get(context));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 绑定
     * @param context
     * @param clazz
     */
    private static final void injectBind(Object context,Class<?> clazz,Bind bind,Field field){
        try {
            //获取到界面UI控件
            Method method=clazz.getMethod("findViewById",int.class);
            View view= (View) method.invoke(context,bind.value());
            //设置属性新值
            field.setAccessible(true);
            field.set(context,view);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
